package com.mspbots.rule.exceptions.triggerEscalation;

import cn.hutool.core.util.StrUtil;
import com.mspbots.cw.request.MessagesDTO;
import com.mspbots.cw.request.TenantUserDTO;
import com.mspbots.cw.request.TriggerEscalationDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Dennis
 */
@Slf4j
@Rule(name = "TriggerEscalationManager", description = "Send messages to manager")
public class TriggerEscalationManager extends TriggerEscalationBaseRule {


    @Condition
    public boolean condition(@Fact(FACT) TriggerEscalationDTO entry) {
        try {
//            if (!setUserMapping(entry.getUserId()) || super.checkMessage(messagesDTO)) {
//                return false;
//            }
            int count = 1;
            Map<String, Object> manager = getManager(entry.getUserId(), entry.getLevel(), count);
            if (!StringUtils.isEmpty(manager.get("result"))) {
                return false;
            }
            if (!setUserMapping(Long.valueOf(String.valueOf(manager.get("manager"))), entry.getTenantId()) || super.checkEscalationManager(entry, manager)) {
                return false;
            }
            return true;
        } catch (Exception e) {
            log.error("TriggerEscalationRule execute error : {}", e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    @Action
    public void action(@Fact(FACT) TriggerEscalationDTO entry) {
        TenantUserDTO tenantUserDTO = tenantUserService.findById(entry.getUserId());
        tenantUserMappingDTO = this.tenantUserMappingService.findByTenantUser(entry.getTenantId(), entry.getUserId());
//        StringBuilder detial = new StringBuilder();
        StringBuilder detial = escalationDetial(entry.getUserId(), entry.getRuleId(), tenantUserService, tenantUserMappingDTO);
        //send to user
        buildUserMessage(entry, tenantUserDTO, detial);

        int count = 1;
        Map<String, Object> manager = getManager(entry.getUserId(), entry.getLevel(), count);

        if (entry.getLevel() == 3) {
            buildMessageToManager(entry, tenantUserDTO, manager, detial);
        }

        String template = null;
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            template = new String(decoder.decode(entry.getTemplate().getBytes()), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //send to manager
        buildManagerMessage(entry, manager, template, tenantUserDTO, detial);
    }

    public Map<String, Object> getManager(Long userId, Long level, int count) {
        TenantUserDTO tenantUserDTOFir = tenantUserService.findById(userId);
        TenantUserDTO tenantUserDTOSec = new TenantUserDTO();
        String firstName = null;
        Map<String, Object> manager = new HashMap<>();
        if ((!StringUtils.isEmpty(tenantUserDTOFir.getManager()))) {
            firstName = getFirstName(tenantUserDTOFir.getManager());
            manager = Map.of("manager", tenantUserDTOFir.getManager(), "tenantUserName", firstName);
            tenantUserDTOSec = tenantUserService.findById(tenantUserDTOFir.getManager());
            if ((!StringUtils.isEmpty(tenantUserDTOSec.getManager())) && level == 3) {
                firstName = getFirstName(tenantUserDTOSec.getManager());
                manager = Map.of("manager", tenantUserDTOSec.getManager(), "tenantUserName", firstName);
            }
        } else {
            Map<String, Object> result = Map.of("result", 0);
            return result;
        }
//        String firstName = null;
//        if((!StringUtils.isEmpty(tenantUserDTOFir.getManager()))){
//            count++;
//            firstName = getFirstName(tenantUserDTOFir.getManager());
//            if(count > level - 1){
//                throw new StopManager();
//            }
//            getManager(tenantUserDTOFir.getManager(),level,count);
//        }else{
//            Map<String, Object> result = Map.of("result",0);
//            return result;
//        }
        return manager;
    }

    public String getFirstName(Long userId) {
        TenantUserDTO tenantUserDTO = tenantUserService.findById(userId);
        String firstName = tenantUserDTO.getFirstname();
        return firstName;
    }

    public void buildUserMessage(TriggerEscalationDTO entry, TenantUserDTO tenantUserDTO, StringBuilder detial) {
        tenantUserMappingDTO = this.tenantUserMappingService.findByTenantUser(entry.getTenantId(), entry.getUserId());
        TenantUserDTO tenantUserDTOManager = tenantUserService.findById(entry.getUserId());
        String manager = getFirstName(tenantUserDTOManager.getManager());
        MessagesDTO messages = new MessagesDTO();
        messages.setUserId(entry.getUserId());
//        messages.setBusinessId(900 + entry.getRuleId() + entry.getUserId());
        messages.setTeamsUserId(tenantUserMappingDTO.getTeamsUserId());
        messages.setRuleId(entry.getRuleId());
        messages.setEscalation(true);
        messages.setTenantId(entry.getTenantId());
        messages.setStatus("Ready");
        messages.setForwardStatus("Ready");
        messages.setType("user");

        String template = "Dear {USER}, you have triggered {TRIGGERNAME} {TIMES} times, your manager {MANAGER} has been notified and will reach out to you for help. Thanks!";
        Map<String, Object> params = new HashMap<>();
        params.put("USER", tenantUserDTO.getFirstname());
        params.put("TRIGGERNAME", "<span style='color:#FF7F00;font-weight:bold'>\"" + entry.getName().replaceAll("(?=(?!^)[A-Z])", " ") + "\"</span>");
        params.put("MANAGER", manager);
        params.put("TIMES", entry.getTimes());
        String message = StrUtil.format(template, params);

        messages.setMessage(message + detial);
        messages.setCreateDate(LocalDateTime.now());
        messages.setExpireDate(messages.getCreateDate().plusHours(12));
        messages.setBusinessType("escalationManager_User");
        MessagesDTO messagesResult = messagesService.insert(messages);
        if (messagesResult != null) {
//                messageProducer.produce(messagesResult);
        }
    }

    public void buildMessageToManager(TriggerEscalationDTO entry, TenantUserDTO tenantUserDTO, Map<String, Object> manager, StringBuilder detial) {
        tenantUserMappingDTO = this.tenantUserMappingService.findByTenantUser(entry.getTenantId(), tenantUserDTO.getManager());
        MessagesDTO messages = new MessagesDTO();
        messages.setUserId(tenantUserDTO.getManager());
//        messages.setBusinessId(900 + entry.getRuleId() + tenantUserDTO.getManager());
        messages.setTeamsUserId(tenantUserMappingDTO.getTeamsUserId());
        messages.setRuleId(entry.getRuleId());
        messages.setEscalation(true);
        messages.setTenantId(entry.getTenantId());
        messages.setStatus("Ready");
        messages.setForwardStatus("Ready");
        messages.setType("Manager");

        String template = "Dear {MANAGER}, {USER} have triggered {TRIGGERNAME} {TIMES} times this week. Please reach out to {USER} to help fixing the issue, " +
                "your manager {NEXTMANAGER} has been notified.";
        Map<String, Object> params = new HashMap<>();
        params.put("USER", tenantUserDTO.getFirstname() + " " + tenantUserDTO.getLastname());
        params.put("TRIGGERNAME", "<span style='color:#FF7F00;font-weight:bold'>\"" + entry.getName().replaceAll("(?=(?!^)[A-Z])", " ") + "\"</span>");
        params.put("TIMES", entry.getTimes());
        params.put("MANAGER", getFirstName(tenantUserDTO.getManager()));
        params.put("NEXTMANAGER", manager.get("tenantUserName"));
        String message = StrUtil.format(template, params);

        messages.setMessage(message + detial);
        messages.setCreateDate(LocalDateTime.now());
        messages.setExpireDate(messages.getCreateDate().plusHours(12));
        messages.setBusinessType("escalationManager_Manager");
        MessagesDTO messagesResult = messagesService.insert(messages);
        if (messagesResult != null) {
//                messageProducer.produce(messagesResult);
        }
    }

    public void buildManagerMessage(TriggerEscalationDTO entry, Map<String, Object> manager, String template, TenantUserDTO tenantUserDTO, StringBuilder detial) {
        tenantUserMappingDTO = this.tenantUserMappingService.findByTenantUser(entry.getTenantId(), Long.valueOf(String.valueOf(manager.get("manager"))));
        TenantUserDTO tenantUserDTOId = tenantUserService.findById(Long.valueOf(String.valueOf(manager.get("manager"))));
        MessagesDTO messages = new MessagesDTO();
        messages.setUserId(Long.valueOf(String.valueOf(manager.get("manager"))));
//        messages.setBusinessId(900 + entry.getRuleId() + Long.valueOf(String.valueOf(manager.get("manager"))));
        messages.setTeamsUserId(tenantUserMappingDTO.getTeamsUserId());
        messages.setRuleId(entry.getRuleId());
        messages.setEscalation(true);
        messages.setTenantId(entry.getTenantId());
        messages.setStatus("Ready");
        messages.setForwardStatus("Ready");
        messages.setType("manager");

        Map<String, Object> params = new HashMap<>();
        params.put("MANAGER", manager.get("tenantUserName"));
        params.put("USER", tenantUserDTO.getFirstname() + " " + tenantUserDTO.getLastname());
        params.put("TRIGGERNAME", "<span style='color:#FF7F00;font-weight:bold'>\"" + entry.getName().replaceAll("(?=(?!^)[A-Z])", " ") + "\"</span>");
        params.put("TIMES", entry.getTimes());
        params.put("NEXTIMES", entry.getNextimes());
        if (!StringUtils.isEmpty(tenantUserDTOId.getManager())) {
            TenantUserDTO tenantUserDTOName = tenantUserService.findById(tenantUserDTOId.getManager());
            params.put("NEXTMANAGER", tenantUserDTOName.getFirstname());
        }
        String message = StrUtil.format(template, params);

        messages.setMessage(message + detial);
        messages.setCreateDate(LocalDateTime.now());
        messages.setExpireDate(messages.getCreateDate().plusHours(12));
        messages.setBusinessType("escalationManager");
        MessagesDTO messagesResult = messagesService.insert(messages);
        if (messagesResult != null) {
//                messageProducer.produce(messagesResult);
        }
    }

}
